﻿"""
中谱补粉机校准系统
"""

# 导入系统与第三方模块
import os
import uuid
from flask import Flask, render_template, redirect, url_for, request, flash, session, send_from_directory
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, IntegerField, FloatField, RadioField
from wtforms.validators import DataRequired, Length, Regexp
from flask_wtf.file import FileField, FileRequired, FileAllowed
from pyautocad import Autocad, APoint
import pyodbc

# 导入自制模块
from weblog import get_logger
from auto_paint import *
from DB_Chip_interval import get_interval

# 初始化日志功能，启动日志记录
logger = get_logger(__name__)
# logger.info("....")

# Flask实例化，加密Cookie
app = Flask(__name__)
app.secret_key = os.getenv('SECRET_KEY', 'secret string')

# 删除Jinja2语句中的空格和制表符
app.jinja_env.trim_blocks = True
app.jinja_env.lstrip_blocks = True

# 上传附件最大10Mb上限
app.config['MAX_CONTENT_LENGTH'] = 10 * 1024 * 1024

# 测试机相关ip字典 192.168.3.247
ip_dict = {'192.168.60.89': 0, '192.168.20.177': 1, '192.168.20.65': 2}
auth_dict = {0: '本机', 1: '旁边机', 2: '包姐'}


# 定义准备校准输入界面表单类，设置相关验证要求
class PrepareCalibration(FlaskForm):
    code = StringField('基板代码', validators=[DataRequired()])
    length = IntegerField('芯片长度(mil)', validators=[DataRequired()])
    width = IntegerField('芯片宽度(mil)', validators=[DataRequired()])
    submit1 = SubmitField('基板代码验证')


# 定义工单下载输入界面表单类，设置相关验证要求
class GenerateCoefficient(FlaskForm):
    serial_number = IntegerField('串数', validators=[DataRequired()])
    union_number = IntegerField('并数', validators=[DataRequired()])
    Dam = FloatField('围坝层数', validators=[DataRequired()])
    submit2 = SubmitField('计算分布情况')


class Form3(FlaskForm):
    choice = RadioField('情况选择', choices=[('1', '情况1'), ('2', '情况2')], validators=[DataRequired()])
    submit3 = SubmitField('生成文件')


# 创建文件上传临时目录
temp_uploads = os.path.join('uploads', 'temp')
if os.path.exists(temp_uploads):
    pass
else:
    os.makedirs(temp_uploads)


# 定义文件修改函数，新文件名为uuid，用于临时存储
def alter_filename(filename):
    ext = os.path.splitext(filename)[1]
    new_filename = uuid.uuid4().hex + ext
    return new_filename


# 注册/路由和cal视图函数
@app.route('/', methods=['GET', 'POST'])
def cal():
    form1 = PrepareCalibration()
    form2 = GenerateCoefficient()
    form3 = Form3()
    # 根据IP地址判定并添加MachineID，服务器ID为0，非分光机台为999
    machine_ip = request.remote_addr
    if machine_ip in ip_dict:
        machine_no = ip_dict[machine_ip]
        if machine_no in auth_dict:
            machine_id = machine_no
        else:
            machine_id = 50
    else:
        machine_id = 50

    # 非授权计算机IP将被重新定向拒绝访问页面
    if machine_id == 999:
        logger.warn(f"{machine_ip} -- 非法访问！")
        return redirect(url_for('reject'))
    # 步骤一操作
    if form1.submit1.data and form1.validate():
        """
        本部分代码要实现的主要功能：
        1. 验证输入基板代码是否存在LES数据
        """
        # 基板代码的验证
        result = code_yz(form1.code.data)
        if result.empty:
            return f"<p>基板代码不存在有效LES值，请检查基板代码是否正确！！</p> " \
                   + f'<br><a href="{url_for("cal")}">返回</a>'
        elif len((set(result['LES_mm']))) > 1:
            return f"<p>基板代码不对应唯一有效的LES值，请检查数据库！！</p> " \
                   + f'<br><a href="{url_for("cal")}">返回</a>'
        else:
            # 将表单相关信息存为字典，方便数据处理,依次是工单号，机台号，工号，工序，标准件，上传文件数据
            session['LES'] = result.loc[0, 'LES_mm']
            session['length'] = form1.length.data
            session['width'] = form1.width.data
            session['code'] = form1.code.data
            return redirect(url_for('cal'))

    # 步骤二操作
    if form2.submit2.data and form2.validate():
        """
        本部分代码要实现的主要功能：
        1. 得出两种情况的数据字典，供第三步选择
        """
        if not session.get('LES') or not session.get('length') or not session.get('width'):
            return f"<p>请确保第一步获得有效的数据并已经显示！！</p> " \
                   + f'<br><a href="{url_for("cal")}">返回</a>'
        else:
            LES = float(session.get('LES'))
            length1 = int(session.get('length')) * 0.0254
            width1 = int(session.get('width')) * 0.0254

            serial_number = form2.serial_number.data
            union_number = form2.union_number.data
            Dam_num = form2.Dam.data
            deviate, interval = get_interval(LES, serial_number, union_number, length1, width1, Dam_num)
            _, total_num1, num_dict1, width_interval1, flag1 = get_info_1(LES, length1, width1, interval, deviate,
                                                                          serial_number, union_number)

            _, total_num2, num_dict2, width_interval2, flag2 = get_info_2(LES, length1, width1, interval, deviate,
                                                                          serial_number, union_number)
            session['serial_number'] = serial_number
            session['union_number'] = union_number
            session['dict1'] = num_dict1
            session['num1'] = total_num1
            session['dict2'] = num_dict2
            session['num2'] = total_num2
            session['deviate'] = deviate
            session['interval'] = interval
            return redirect(url_for('cal'))

    # 步骤三
    if form3.submit3.data and form3.validate():
        """
        本部分代码要实现的主要功能：
        1. 根据选择的情况，生成文件
        """
        if not session.get('LES') or not session.get('length') or not session.get('width'):
            return f"<p>请确保第一步获得有效的数据并已经显示！！</p> " \
                   + f'<br><a href="{url_for("cal")}">返回</a>'
        elif not session.get('serial_number') or not session.get('union_number') or not session.get('deviate') \
                or not session.get('interval'):
            return f"<p>请确保第二步获得有效的数据并已经显示！！</p> " \
                   + f'<br><a href="{url_for("cal")}">返回</a>'
        else:
            LES = float(session.get('LES'))
            length1 = int(session.get('length')) * 0.0254
            width1 = int(session.get('width')) * 0.0254
            serial_number = session.get('serial_number')
            union_number = session.get('union_number')
            deviate = session.get('deviate')
            interval = session.get('interval')

            try:
                if form3.choice.data == '1' and session.get('dict1'):
                    Main('1', LES, length1, width1, interval, deviate, serial_number, union_number)
                    session.clear()
                elif form3.choice.data == '2' and session.get('dict2'):
                    Main('2', LES, length1, width1, interval, deviate, serial_number, union_number)
                    session.clear()
                else:
                    return f"<p>对应情况无法做图！！</p> " \
                           + f'<br><a href="{url_for("cal")}">返回</a>'
            except Exception as e:
                return f"<p>程序错误,请返回重试！！<br>----{e}-----</p> " \
                       + f'<br><a href="{url_for("delete")}">返回</a>'
            else:
                return send_from_directory('E:/Desktop/CAD/Download', filename='PyAutoCAD_SaveAs.dwg', as_attachment=True)

    # 渲染出cal.html这个页面(让页面显示在浏览器上)
    return render_template('cal.html', form1=form1, form2=form2, form3=form3,
                           LES=session.get('LES'), code=session.get('code'), length=session.get('length'),
                           width=session.get('width'), dict1=session.get('dict1'), dict2=session.get('dict2'),
                           num1=session.get('num1'),num2=session.get('num2'),
                           serial_number=session.get('serial_number'),union_number=session.get('union_number'),
                           deviate=session.get('deviate'),interval=session.get('interval'))


# 注册/reject路由和reject视图函数
@app.route('/delete', methods=['GET'])
def delete():
    session.clear()
    return redirect(url_for('cal'))


# 主程序入口
if __name__ == '__main__':
    app.run(debug=True)
